"""Kismet REST API SHEDULER API"""
import time
import sched
import json
import logging
import configparser
import telebot
import requests

LOG_FILE = "kismet-sensor.log"

configparser = configparser.RawConfigParser()
CONFIGFILE = r'.env\kismet-api.conf'
configparser.read(CONFIGFILE)

tg_token = configparser.get('telegram', 'tg_token')
tg_chat_id = configparser.get('telegram', 'tg_chat_id')
telegram_notify = configparser.getboolean('telegram', 'telegram_notify')
kismet_ip = configparser.get('server', 'kismet_ip')
kismet_port = configparser.get('server', 'kismet_port')
kismet_username = configparser.get('server', 'kismet_username')
kismet_password = configparser.get('server', 'kismet_password')
kismet_api = configparser.get('server', 'kismet_api')
CHECK_INTERVAL = int(configparser.get('server', 'check_interval'))
CHECK_INTERVAL_AP = int(configparser.get('server', 'CHECK_INTERVAL_AP'))

KISMET_ENDPOINT = f"https://{kismet_username}:{kismet_password}@{kismet_ip}:{kismet_port}"


CONFIGFILE = r'alert.conf'
configparser.read(CONFIGFILE)
mac_white_list = json.loads(configparser.get('alerts', 'mac_white_list'))
ap_white_list = json.loads(configparser.get('alerts', 'ap_white_list'))
ap_alert_list = json.loads(configparser.get('alerts', 'ap_alert_list'))
mac_alert_list =json.loads(configparser.get('alerts', 'mac_alert_list'))
device_alert_list =json.loads(configparser.get('alerts', 'device_alert_list'))
send_system_alerts = configparser.getboolean('alerts','send_system_alerts')

logging.basicConfig(filename=LOG_FILE,  \
    format='%(asctime)s %(levelname)s %(message)s', level=logging.INFO)

logging.info("Starting Kismet Watcher at %s:%s, checking every %s seconds", \
    str(kismet_ip), str(kismet_port), CHECK_INTERVAL)

# Initialize the scheduler
scheduler = sched.scheduler(timefunc=time.time)

bot = telebot.TeleBot(tg_token)

def send_tg(message):
    """Send Telegram message if enabled in config"""
    if telegram_notify and message:
        try:
            bot.send_message(tg_chat_id, message)
        except Exception as e:
            logging.error("Error sendind data to telegram: %s", e)
        return

def fetch_and_check_kismet_data():
    """ fetch data from kismet endpoint """
    req = f"{KISMET_ENDPOINT}/devices/last-time/{-CHECK_INTERVAL}/devices.json"
    logging.debug("Fetching data from source")
    try:
        response = requests.get(req, timeout=5)
        data = json.loads(response.text)
    except Exception as e:
        logging.error("unable fetching data from kismet: %s", e)
        response = "error"
        return

# new module for find

    for device in data:
#find mac in mac_alert_list AND not in mac_white_list
        for mac_in_alert_list in mac_alert_list:
 
            check1 = device['kismet.device.base.macaddr'].startswith(mac_in_alert_list)
            check2 = device['kismet.device.base.macaddr'] not in mac_white_list

            if  check1 and check2:
                message_text = f'[Warning]:  Device in MAC alertlist detected:\
                    {device["kismet.device.base.macaddr"]} \
                    {device["kismet.device.base.commonname"]} {device["kismet.device.base.name"]}'
                logging.warning(message_text)
                send_tg(message_text)

        for ap in ap_alert_list: #Only WiFi-AP
            check1 = (device['kismet.device.base.commonname'].find(ap) > -1 \
                and device['kismet.device.base.type'] == "Wi-Fi AP")
            check2 = device['kismet.device.base.commonname'] not in ap_white_list
            check3 = device['kismet.device.base.macaddr'] not in mac_white_list
  
            if check1 and check2 and check3:
                message_text = f'[Warning]: WiFi AP in list "{ap}" detected: \n \
                    {device["kismet.device.base.commonname"]} \n \
                    {device["kismet.device.base.manuf"]} \n \
                    {device["kismet.device.base.macaddr"]} \n \
                    {device["kismet.device.base.crypt"]} \
                    '
                logging.warning(message_text)
                send_tg(message_text)


        for dev in device_alert_list: #find device names
            check1 = device['kismet.device.base.commonname'].find(dev) > -1
            check2 = device['kismet.device.base.macaddr']  not in mac_white_list
            if check1 and check2:
                message_text = f'[Warning]: Device in list "{dev}" detected: \
                    {device["kismet.device.base.macaddr"]} \
                    {device["kismet.device.base.commonname"]} \
                    {device["kismet.device.base.name"]}, {device["kismet.device.base.type"]}, \
                    {device["kismet.device.base.crypt"]}'
                logging.warning(message_text)
                send_tg(message_text)


def fetch_and_check_kismet_alerts():
    """fetch alerts from kismet endpoint"""
    c=int(time.time()-CHECK_INTERVAL)
    req = f"{KISMET_ENDPOINT}/alerts/last-time/{c}/alerts.json"
    try:
        response = requests.get(req, timeout=5)
        data = json.loads(response.text)
    except Exception as e:
        logging.error("Error fetching alerts from kismet: %s", e)
        return
    message_text = ""

    for alert in data:
        l = len(data)
        check1 = alert["kismet.alert.class"] == "SYSTEM"
        check2 = send_system_alerts is True
        c, c1 = 0, 0
        if  check1 is True  and check2 is False:
            pass
        else:
            message_text = message_text + f'[Alert]: {alert["kismet.alert.text"]}\
                {alert["kismet.alert.transmitter_mac"]} \n \n'

            logging.warning(f'{alert["kismet.alert.text"]} {alert["kismet.alert.transmitter_mac"]}')

            c = c + 1
            c1 = c1 + 1
            if c > 5 and c1 < 3:   
                send_tg(message_text)
                message_text = ""
                c = 0
                c1 = c1 + 1
            else:
                if c1 > 4:
                    message_text = f'[WARNING] To many messages {l} detected. Check logs. Attack is possible'
                    send_tg(message_text)
                    message_text = ""
                    c = 0
                    c1 = 0
                    return
            if c1 > 4:
                message_text = ""
                с1 = 0
                return
        if message_text:
            send_tg(message_text)
            message_text = ""

def fetch_and_get_ssids():
    """ fetch data from kismet endpoint and get all SSIDs"""
    req = f"{KISMET_ENDPOINT}/devices/last-time/{-CHECK_INTERVAL_AP}/devices.json"
    try:
        response = requests.get(req, timeout=5)
        data = json.loads(response.text)
    except Exception as e:
        logging.error("Error fetching data from kismet: %s", e)
        response = "error"
        return

    ssid_list = ""
    for device in data:
        check1 = device['kismet.device.base.type'] == "Wi-Fi AP"
        check2 = device['kismet.device.base.commonname'] not in ap_white_list
        check3 = device['kismet.device.base.macaddr'] not in mac_white_list
        if check1 and check2 and check3:
            ssid_list = ssid_list + device['kismet.device.base.commonname']  \
               + " " + device['kismet.device.base.macaddr'] \
               + " " + device['kismet.device.base.manuf'] \
               + " " + device['kismet.device.base.crypt'] \
               + " " + device['kismet.device.base.channel'] \
               + "\n"

    print(ssid_list)
    print("Total AP: ", len(ssid_list.splitlines()))

def run_scheduler():
    """Schedule the function to run after check_interval seconds"""
    scheduler.enter(CHECK_INTERVAL, 1, run_scheduler)
    fetch_and_check_kismet_data()
    fetch_and_check_kismet_alerts()


if __name__ == "__main__":
    scheduler.enter(CHECK_INTERVAL, 1, run_scheduler)
    scheduler.enter(CHECK_INTERVAL_AP, 1, fetch_and_get_ssids)
    scheduler.run()
